package com.app.system.permission.service;

import com.app.system.jpa.JpaBaseDao;
import com.app.system.permission.dao.SysPermissionDao;
import com.app.system.permission.en.ResourceType;
import com.app.system.permission.model.SysPermission;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.app.system.utils.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * Created by wcf-pc on 2018/5/24.
 */
@Service
@SuppressWarnings("all")
@CacheConfig(cacheNames = {"sysPermissionCache"})
public class SysPermissionService extends JpaBaseDao<SysPermission, Integer> {


    @Resource
    private SysPermissionDao sysPermissionDao;

    //清空所有缓存
    @CacheEvict(value = {"userInfoCache", "sysRoleCache", "sysPermissionCache"}, allEntries = true)
    @Transactional
    public String deleteByIds(String[] ids) {
        if (ids.length > 0) {
            List<Integer> idsList = Lists.newArrayList();
            for (String id : ids) {
                idsList.add(Integer.valueOf(id));
            }
            this.sysPermissionDao.deleteByIds(idsList);
        }
        return "ok";
    }

    //清空所有缓存
    @CacheEvict(value = {"userInfoCache", "sysRoleCache", "sysPermissionCache"}, allEntries = true)
    @Transactional
    public String deleteById(Integer id) {
        this.sysPermissionDao.delete(id);
        return "ok";
    }

    //清空所有缓存
    @CacheEvict(value = {"userInfoCache", "sysRoleCache", "sysPermissionCache"}, allEntries = true)
    @Transactional
    @Override
    public void save(SysPermission sysPermission) {
        this.sysPermissionDao.save(sysPermission);
    }

    /**
     * 树形菜单所需要的
     *
     * @return
     */
    @Cacheable(key = "targetClass + methodName")
    public List<Map> mapTreeData() {
        List<SysPermission> sysPermissionList = this.sysPermissionDao.findParentList(ResourceType.menu.toString());
        List<Map> result = Lists.newArrayList();
        this.childrenData(sysPermissionList, result);
        return result;
    }

    private void childrenData(List<SysPermission> dataList, List<Map> result) {
        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }
        Map map = null;
        List<SysPermission> itemList = null;
        List<Map> childrenList = null;
        for (SysPermission sysPermission : dataList) {
            if (sysPermission.getResourceType().equals(ResourceType.menu.toString())) {
                map = null;
                map = Maps.newHashMap();
                String enabledStr = "";
                if (sysPermission.getEnabled().intValue() == 1) {
                    enabledStr = "<span style='color:red;'>[禁用]</span>";
                }
                map.put("id", sysPermission.getId());
                map.put("name", enabledStr + sysPermission.getName() + "[" + sysPermission.getSortIndex() + "]");
                map.put("open", true);
                itemList = null;
                childrenList = null;
                itemList = sysPermission.getSysPermissionList();
                if (!CollectionUtils.isEmpty(itemList)) {
                    childrenList = Lists.newArrayList();
                    this.childrenData(itemList, childrenList);
                    map.put("children", childrenList);
                }
                result.add(map);
            }
        }
    }

    @Cacheable(key = "targetClass + methodName")
    public List<Map> mapPermissionJsonData() {
        List<SysPermission> sysPermissionList = this.sysPermissionDao.findParentList(ResourceType.menu.toString());
        List<Map> result = Lists.newArrayList();
        this.childrenPermissionJson(sysPermissionList, result);
        return result;
    }

    private void childrenPermissionJson(List<SysPermission> dataList, List<Map> result) {
        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }
        Map map = null;
        List<SysPermission> itemList = null;
        for (SysPermission sysPermission : dataList) {
            map = null;
            map = Maps.newHashMap();
            String enabledStr = "";
            if (sysPermission.getEnabled().intValue() == 1) {
                enabledStr = "<span style='color:red;'>[禁用]</span>";
            }
            map.put("id", sysPermission.getId());
            map.put("pid", sysPermission.getSysPermission() != null ? sysPermission.getSysPermission().getId() : 0);
            map.put("name", enabledStr + sysPermission.getName());
            itemList = sysPermission.getSysPermissionList();
            if (!CollectionUtils.isEmpty(itemList)) {
                this.childrenPermissionJson(itemList, result);
            }
            result.add(map);
        }
    }

    @Cacheable(key = "targetClass + methodName +#p0")
    public List<SysPermission> findListByParentId(int parentId) {
        return this.sysPermissionDao.findListByParentId(parentId, ResourceType.button.toString());
    }

    @Cacheable(key = "targetClass + methodName +#p0")
    @Override
    public SysPermission findOne(Integer id) {
        return this.sysPermissionDao.findOne(id);
    }


    private List<Integer> getUsernamePermissionId(String username) {
        Map<String, Object> params = Maps.newHashMap();
        StringBuffer sql = new StringBuffer("select rp.permission_id as id from sys_role_permission rp");
        sql.append(" where exists (select 1 from sys_user_role sr where rp.role_id = sr.role_id and exists (select 1 from user_info uf where uf.id = sr.uid and uf.username = :username))");
        params.put("username", username);
        return (List<Integer>) this.findSqlObject(sql.toString(), params);
    }

    @Cacheable(key = "targetClass + methodName +#p0")
    public List<SysPermission> findListByUsername(String username) {
        List<Integer> permissionIdList = this.getUsernamePermissionId(username);
        permissionIdList = CollectionUtils.isEmpty(permissionIdList) ? Lists.newArrayList() : permissionIdList;

        List<SysPermission> list = this.sysPermissionDao.findListByUserName(true, username);

        List<SysPermission> resultLists = Lists.newLinkedList();
        removeUsernameNotPermissionId(resultLists, list, permissionIdList);

        return resultLists;
    }

    /**
     * 根据用户名获取一级菜单
     *
     * @param username
     * @return
     */
    public List<SysPermission> findRootMenuByUername(String username) {
        List<SysPermission> list = this.sysPermissionDao.findListByUserName(true, username);
        return list;
    }

    private void removeUsernameNotPermissionId(List<SysPermission> resultLists, List<SysPermission> list, List<Integer> permissionIdList) {
        if (CollectionUtils.isNotEmpty(list)) {
            List<SysPermission> itemList = null;
            SysPermission itemSysPermission = null;
            for (SysPermission sysPermission : list) {

                itemSysPermission = null;
                itemList = null;

                if (permissionIdList.contains(sysPermission.getId())) {
                    itemSysPermission = new SysPermission();
                    itemSysPermission = sysPermission;

                    itemList = Lists.newLinkedList();

                    removeUsernameNotPermissionId(itemList, sysPermission.getSysPermissionList(), permissionIdList);

                    itemSysPermission.setSysPermissionList(itemList);
                    resultLists.add(itemSysPermission);
                }
            }
        }
    }
}
